package com.gjy.shiro.simple;

import com.google.common.collect.Sets;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-09-01 15:00:04
 */
public class SimpleRealm extends AuthorizingRealm {

    private static final Logger log = LoggerFactory.getLogger(SimpleRealm.class);

    // 模拟 DAO
    private static final Map<String, UserInfo> USER_REPO = new HashMap<>();

    static {
        UserInfo alice = new UserInfo("alice", PasswordUtil.md5("secret"), Sets.newHashSet("user"), Sets.newHashSet("emp:view"));
        UserInfo bob = new UserInfo("bob", PasswordUtil.md5("123456"), Sets.newHashSet("admin"), Sets.newHashSet("emp:view", "emp:edit", "emp:delete"));
        USER_REPO.put("alice", alice);
        USER_REPO.put("bob", bob);
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        UserInfo user = USER_REPO.get(username);

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(user.getRoles());
        info.setStringPermissions(user.getPermissions());
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        UserInfo user = USER_REPO.get(username);
        if (user == null) {
            throw new UnknownAccountException("用户不存在：" + username);
        }

        // 返回盐值加密后的密码，用于 Shiro 做比对
        return new SimpleAuthenticationInfo(
                user.getUsername(),            // principal
                user.getPasswordMd5(),         // hashed credentials
                ByteSource.Util.bytes(username), // salt 用用户名即可
                getName()                      // realm name
        );
    }
}
